home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
xscheme.arc
/
xsfun1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-01-29
|
20KB
|
1,020 lines
/* xsfun1.c - xscheme built-in functions - part 1 */
/* Copyright (c) 1988, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xscheme.h"
/* gensym variables */
static char gsprefix[STRMAX+1] = { 'G',0 }; /* gensym prefix string */
static int gsnumber = 1; /* gensym number */
/* external variables */
extern LVAL xlenv,xlval,default_object,true;
extern LVAL s_unbound;
/* external routines */
extern int eq(),eqv(),equal();
/* forward declarations */
FORWARD LVAL cxr();
FORWARD LVAL member();
FORWARD LVAL assoc();
FORWARD LVAL nth();
FORWARD LVAL eqtest();
/* xcons - construct a new list cell */
LVAL xcons()
{
LVAL carval,cdrval;
/* get the two arguments */
carval = xlgetarg();
cdrval = xlgetarg();
xllastarg();
/* construct a new cons node */
return (cons(carval,cdrval));
}
/* xcar - built-in function 'car' */
LVAL xcar()
{
LVAL list;
list = xlgalist();
xllastarg();
return (list ? car(list) : NIL);
}
/* xicar - built-in function '%car' */
LVAL xicar()
{
LVAL cons;
cons = xlgetarg();
xllastarg();
return (car(cons));
}
/* xcdr - built-in function 'cdr' */
LVAL xcdr()
{
LVAL list;
list = xlgalist();
xllastarg();
return (list ? cdr(list) : NIL);
}
/* xicdr - built-in function '%cdr' */
LVAL xicdr()
{
LVAL cons;
cons = xlgetarg();
xllastarg();
return (cdr(cons));
}
/* cxxr functions */
LVAL xcaar() { return (cxr("aa")); }
LVAL xcadr() { return (cxr("da")); }
LVAL xcdar() { return (cxr("ad")); }
LVAL xcddr() { return (cxr("dd")); }
/* cxxxr functions */
LVAL xcaaar() { return (cxr("aaa")); }
LVAL xcaadr() { return (cxr("daa")); }
LVAL xcadar() { return (cxr("ada")); }
LVAL xcaddr() { return (cxr("dda")); }
LVAL xcdaar() { return (cxr("aad")); }
LVAL xcdadr() { return (cxr("dad")); }
LVAL xcddar() { return (cxr("add")); }
LVAL xcdddr() { return (cxr("ddd")); }
/* cxxxxr functions */
LVAL xcaaaar() { return (cxr("aaaa")); }
LVAL xcaaadr() { return (cxr("daaa")); }
LVAL xcaadar() { return (cxr("adaa")); }
LVAL xcaaddr() { return (cxr("ddaa")); }
LVAL xcadaar() { return (cxr("aada")); }
LVAL xcadadr() { return (cxr("dada")); }
LVAL xcaddar() { return (cxr("adda")); }
LVAL xcadddr() { return (cxr("ddda")); }
LVAL xcdaaar() { return (cxr("aaad")); }
LVAL xcdaadr() { return (cxr("daad")); }
LVAL xcdadar() { return (cxr("adad")); }
LVAL xcdaddr() { return (cxr("ddad")); }
LVAL xcddaar() { return (cxr("aadd")); }
LVAL xcddadr() { return (cxr("dadd")); }
LVAL xcdddar() { return (cxr("addd")); }
LVAL xcddddr() { return (cxr("dddd")); }
/* cxr - common car/cdr routine */
LOCAL LVAL cxr(adstr)
char *adstr;
{
LVAL list;
/* get the list */
list = xlgalist();
xllastarg();
/* perform the car/cdr operations */
while (*adstr && consp(list))
list = (*adstr++ == 'a' ? car(list) : cdr(list));
/* make sure the operation succeeded */
if (*adstr && list)
xlbadtype(list);
/* return the result */
return (list);
}
/* xsetcar - built-in function 'set-car!' */
LVAL xsetcar()
{
LVAL arg,newcar;
/* get the cons and the new car */
arg = xlgacons();
newcar = xlgetarg();
xllastarg();
/* replace the car */
rplaca(arg,newcar);
return (arg);
}
/* xisetcar - built-in function '%set-car!' */
LVAL xisetcar()
{
LVAL arg,newcar;
/* get the cons and the new car */
arg = xlgetarg();
newcar = xlgetarg();
xllastarg();
/* replace the car */
rplaca(arg,newcar);
return (arg);
}
/* xsetcdr - built-in function 'set-cdr!' */
LVAL xsetcdr()
{
LVAL arg,newcdr;
/* get the cons and the new cdr */
arg = xlgacons();
newcdr = xlgetarg();
xllastarg();
/* replace the cdr */
rplacd(arg,newcdr);
return (arg);
}
/* xisetcdr - built-in function '%set-cdr!' */
LVAL xisetcdr()
{
LVAL arg,newcdr;
/* get the cons and the new cdr */
arg = xlgetarg();
newcdr = xlgetarg();
xllastarg();
/* replace the cdr */
rplacd(arg,newcdr);
return (arg);
}
/* xlist - built-in function 'list' */
LVAL xlist()
{
LVAL last,next,val;
/* initialize the list */
val = NIL;
/* add each argument to the list */
if (moreargs()) {
val = last = cons(nextarg(),NIL);
while (moreargs()) {
next = nextarg();
push(val);
next = cons(next,NIL);
rplacd(last,next);
last = next;
val = pop();
}
}
/* return the list */
return (val);
}
/* xappend - built-in function 'append' */
LVAL xappend()
{
LVAL next,this,last,val;
/* append each argument */
for (val = last = NIL; xlargc > 1; )
/* append each element of this list to the result list */
for (next = xlgalist(); consp(next); next = cdr(next)) {
push(val);
this = cons(car(next),NIL);
val = pop();
if (last == NIL) val = this;
else rplacd(last,this);
last = this;
}
/* tack on the last argument */
if (moreargs()) {
if (last == NIL) val = xlgetarg();
else rplacd(last,xlgetarg());
}
/* return the list */
return (val);
}
/* xreverse - built-in function 'reverse' */
LVAL xreverse()
{
LVAL next,val;
/* get the list to reverse */
next = xlgalist();
xllastarg();
/* append each element of this list to the result list */
for (val = NIL; consp(next); next = cdr(next)) {
push(val);
val = cons(car(next),top());
drop(1);
}
/* return the list */
return (val);
}
/* xlastpair - built-in function 'last-pair' */
LVAL xlastpair()
{
LVAL list;
/* get the list */
list = xlgalist();
xllastarg();
/* find the last cons */
if (consp(list))
while (consp(cdr(list)))
list = cdr(list);
/* return the last element */
return (list);
}
/* xlength - built-in function 'length' */
LVAL xlength()
{
FIXTYPE n;
LVAL arg;
/* get the argument */
arg = xlgalist();
xllastarg();
/* find the length */
for (n = (FIXTYPE)0; consp(arg); ++n)
arg = cdr(arg);
/* return the length */
return (cvfixnum(n));
}
/* xmember - built-in function 'member' */
LVAL xmember()
{
return (member(equal));
}
/* xmemv - built-in function 'memv' */
LVAL xmemv()
{
return (member(eqv));
}
/* xmemq - built-in function 'memq' */
LVAL xmemq()
{
return (member(eq));
}
/* member - common routine for member/memv/memq */
LOCAL LVAL member(fcn)
int (*fcn)();
{
LVAL x,list,val;
/* get the expression to look for and the list */
x = xlgetarg();
list = xlgalist();
xllastarg();
/* look for the expression */
for (val = NIL; consp(list); list = cdr(list))
if ((*fcn)(x,car(list))) {
val = list;
break;
}
/* return the result */
return (val);
}
/* xassoc - built-in function 'assoc' */
LVAL xassoc()
{
return (assoc(equal));
}
/* xassv - built-in function 'assv' */
LVAL xassv()
{
return (assoc(eqv));
}
/* xassq - built-in function 'assq' */
LVAL xassq()
{
return (assoc(eq));
}
/* assoc - common routine for assoc/assv/assq */
LOCAL LVAL assoc(fcn)
int (*fcn)();
{
LVAL x,alist,pair,val;
/* get the expression to look for and the association list */
x = xlgetarg();
alist = xlgalist();
xllastarg();
/* look for the expression */
for (val = NIL; consp(alist); alist = cdr(alist))
if ((pair = car(alist)) && consp(pair))
if ((*fcn)(x,car(pair),fcn)) {
val = pair;
break;
}
/* return the result */
return (val);
}
/* xlistref - built-in function 'list-ref' */
LVAL xlistref()
{
return (nth(TRUE));
}
/* xlisttail - built-in function 'list-tail' */
LVAL xlisttail()
{
return (nth(FALSE));
}
/* nth - internal nth function */
LOCAL LVAL nth(carflag)
int carflag;
{
LVAL list,arg;
int n;
/* get n and the list */
list = xlgalist();
arg = xlgafixnum();
xllastarg();
/* range check the index */
if ((n = (int)getfixnum(arg)) < 0)
xlerror("index out of range",arg);
/* find the nth element */
for (; consp(list) && n; n--)
list = cdr(list);
/* make sure the list was long enough */
if (n)